package com.ex.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.support.HibernateDaoSupport;

import com.ex.dao.BaseDao;
import com.ex.model.TTeacher;

public class BaseDaoImpl<T, PK extends Serializable> extends HibernateDaoSupport implements BaseDao<T, PK> {

	@Autowired
	private HibernateTemplate hibernateTemplate;

	private Class<T> clazz;
	
	@Resource(name = "sessionFactory")
	public void setSuperSessionFactory(SessionFactory sessionFactory) {
		this.setSessionFactory(sessionFactory);
		//super.setSessionFactory(sessionFactory);
	}

	public BaseDaoImpl() {

		clazz =(Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];

	}

	public T findById(PK id) {
		T t = (T) hibernateTemplate.get(clazz, id);
		return t;
	}

	@Override
	public List query(String hql, Object[] obj) {
		List list = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<obj.length;i++){
					query.setParameter(i, obj[i]);
				}
				return query.list();
			}
		});
		// TODO Auto-generated method stub
		return list;
	}
	
	@Override
	public List queryBySQL(String hql, Object[] obj) {
		List list = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createSQLQuery(hql);				
				for(int i=0;i<obj.length;i++){
					query.setParameter(i, obj[i]);
				}
				return query.list();
			}
		});
		// TODO Auto-generated method stub
		return list;
	}
	
	public <T> List<T> pageBean(final String hql, final int pageStart, final int pageSize ,final Object... conditions) {
		List list = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				Query query = session.createQuery(hql);				
				for(int i=0;i<conditions.length;i++){
					query.setParameter(i, conditions[i]);
				}
				query.setFirstResult(pageStart);
				query.setMaxResults(pageSize);
				return query.list();
			}
		});
		return list;
	}
	
	@Override
	public List test(String hql, Object[] obj) {
		List list = (List) this.getHibernateTemplate().execute(new HibernateCallback() {
			@Override
			public Object doInHibernate(Session session) throws HibernateException {
				SQLQuery query = session.createSQLQuery(hql);				
				for(int i=0;i<obj.length;i++){
					query.setParameter(i, obj[i]);
				}
				query.addEntity(TTeacher.class);
				return query.list();
			}
		});
		// TODO Auto-generated method stub
		return list;
	}	
}
